import $time from 'moment'
import kdApis from '/api/modularApi/kdApi.js'

const msg = (msg, type, offset, duration) => {
	uni.showToast({
		title: msg,
		icon: "none"
	})
}

const confirm = (msg, confirmTxt) => {
	return new Promise((resolve, reject) => {
		uni.showModal({
			title: confirmTxt ? confirmTxt : "提示",
			content: msg,
			success: function(res) {
				if (res.confirm) {
					resolve()
				} else if (res.cancel) {
					reject()
				}
			}
		})
	})
}

// 准确判断数据类型 [IE]  String | Undefined | Array | Object | Boolean | Number | Null | Function
// 参考地址：https://blog.csdn.net/qq_41800366/article/details/114624177
const getType = (variable) => {
	return Object.prototype.toString.call(variable).replace(/^\[object (\w+)\]$/, '$1')
}

// Json 转 Url [IE]
const jsonToUrl = (json, appointFieldArr, ignoreFieldArr) => {
	if (getType(json) !== "Object" || JSON.stringify(json) == "{}") return ""
	let newJson = JSON.parse(JSON.stringify(json))
	// 如果不指定字段则全部转换，如果指定了字段则无视忽视字段
	if (getType(appointFieldArr) == "Array" && appointFieldArr.length) {
		// IE 不支持for...of forEach
		let temObj = {}
		for (let i = 0; i < appointFieldArr.length; i++) {
			temObj[appointFieldArr[i]] = newJson[appointFieldArr[i]]
		}
		newJson = temObj
	} else {
		if (getType(ignoreFieldArr) == "Array" && ignoreFieldArr.length) {
			for (let key in newJson) {
				if (ignoreFieldArr.includes(key)) delete newJson[key]
			}
		}
	}
	try {
		return new URLSearchParams(newJson).toString()
	} catch (error) {
		let urlStr = ""
		for (let key in newJson) {
			urlStr += key + "=" + newJson[key] + "&"
		}
		return urlStr.substr(0, urlStr.length - 1)
	}
}

// Url/href 转 Json [IE]
const urlToJson = (url) => {
	if (getType(url) !== "String" || !url) return {}

	// 转换多余的 ? 云之家可能出现这种问题
	let temArr = url.split("?")
	if (temArr.length > 2) url = temArr.join("&").replace("&", "?")

	let reg_url = /^[^\?]+\?([\w\W]+)$/,
		reg_para = /([^&=]+)=([\w\W]*?)(&|$|#)/g,
		arr_url = reg_url.exec(url),
		ret = {}
	if (arr_url && arr_url[1]) {
		let str_para = arr_url[1],
			result
		while ((result = reg_para.exec(str_para)) != null) {
			ret[result[1]] = result[2]
		}
	}
	return ret
}

// href 中提取某一个参数 [IE]
const hrefQueryString = (name) => {
	var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i")
	var r = window.location.search.substr(1).match(reg)
	if (r != null) return unescape(r[2])
	return null
}

// 获取当前页面缩放比例
const detectZoom = () => {
	var ratio = 0,
		screen = window.screen,
		ua = navigator.userAgent.toLowerCase()
	if (window.devicePixelRatio !== undefined) {
		ratio = window.devicePixelRatio
	} else if (~ua.indexOf('msie')) {
		if (screen.deviceXDPI && screen.logicalXDPI) {
			ratio = screen.deviceXDPI / screen.logicalXDPI
		}
	} else if (window.outerWidth !== undefined && window.innerWidth !== undefined) {
		ratio = window.outerWidth / window.innerWidth
	}
	if (ratio) {
		ratio = Math.round(ratio * 100)
	}
	return ratio
}

// 当前浏览器是否是IE浏览器
const isIE = () => {
	var userAgent = navigator.userAgent //取得浏览器的userAgent字符串  
	var isIE = userAgent.indexOf("compatible") > -1 && userAgent.indexOf("MSIE") > -1 //判断是否IE<11浏览器  
	var isEdge = userAgent.indexOf("Edge") > -1 && !isIE //判断是否IE的Edge浏览器  
	var isIE11 = userAgent.indexOf('Trident') > -1 && userAgent.indexOf("rv:11.0") > -1
	if (isIE) {
		var reIE = new RegExp("MSIE (\\d+\\.\\d+)")
		reIE.test(userAgent)
		var fIEVersion = parseFloat(RegExp["$1"])
		if (fIEVersion == 7) {
			return true
		} else if (fIEVersion == 8) {
			return true
		} else if (fIEVersion == 9) {
			return true
		} else if (fIEVersion == 10) {
			return true
		} else {
			return true //IE版本<=7
		}
	} else if (isEdge) {
		return false
	} else if (isIE11) {
		return true //IE11  
	} else {
		return false //不是ie浏览器
	}
}

// Json数组转树 [IE×]
const arraytoTree = (arr) => {
	if (getType(arr) !== "Array" || !arr) return []
	let temArr = JSON.parse(JSON.stringify(arr))
	let resultList = []
	let sourceMap = {}
	temArr.forEach(item => {
		item.level = 0
		sourceMap[item.Id] = item
	})
	temArr.forEach(item => {
		let parent = sourceMap[item.ParentId]
		if (parent) {
			item.level = parent.level + 1
			item.Path = `${parent.Path}/${item.Id}`;
			(parent.children || (parent.children = [])).push(item)
		} else {
			item.level = 0
			item.Path = item.Id
			resultList.push(item)
		}
	})
	return resultList
}

// 树形转Json数组
const treeToArray = (tree) => {
	if (getType(tree) !== "Array" || !tree) return []
	let sourceTree = JSON.parse(JSON.stringify(tree))
	return sourceTree.reduce((pre, cur) => {
		pre = pre.concat(cur).concat(cur.children && cur.children.length > 0 ? treeToArray(cur.children) : [])
		if (cur.children && cur.children.length) cur.hasChild = true
		delete cur.children
		return pre
	}, [])
}

// 表单验证
const checkForm = (form, rules, checkNumber0, checkNumberNegative) => {
	return new Promise((resolve, reject) => {
		for (let key in rules) {
			let value = form[key]
			let errMsg = ""
			switch (getType(value)) {
				case "String":
					if (value.trim() == "") errMsg = rules[key]
					break;
				case "Array":
					if (value.length == 0) errMsg = rules[key]
					break;
				case "Object":
					if (JSON.stringify(value) == "{}") errMsg = rules[key]
					break;
				case "Number":
					if (checkNumber0 && value == 0) {
						errMsg = rules[key].slice(3) + "不能输入数字 0 ！";
						break;
					}
					if (checkNumberNegative && value < 0) {
						errMsg = rules[key].slice(3) + "不能输入负数 ！";
						break;
					}
					break;
				default:
					if (!value) errMsg = rules[key]
					break;
			}
			if (errMsg) return msg(errMsg, 'error')
		}
		resolve()
	})
}

// 数组中的元素是否包含某些相同的键值对
const hIncludes = (arr, item, filedList) => {
	let index = -1
	if (getType(arr) !== "Array" || getType(item) !== "Object") return flag
	if (filedList) {
		index = arr.findIndex(iter => {
			let same = true
			filedList.forEach(it => {
				if (iter[it] !== item[it]) same = false
			})
			return same
		})
	} else {
		index = arr.findIndex(iter => {
			let same = true
			for (let key in item) {
				if (item[key] !== iter[key]) {
					same = false
				}
			}
			return same
		})
	}
	return index
}

// 对比两个数组，返回较老数组减少的元素，返回较老数组新增的元素
const contrastArr = (oldArr, newArr, keyStr) => {
	let obj = {
		ReducedEle: [],
		NewEle: []
	}
	if (getType(oldArr) !== "Array" || !oldArr || getType(newArr) !== "Array" || !newArr || !keyStr) return obj
	obj.ReducedEle = oldArr.filter(item => newArr.findIndex(it => item[keyStr] == it[keyStr]) == -1)
	obj.NewEle = newArr.filter(item => oldArr.findIndex(it => item[keyStr] == it[keyStr]) == -1)
	return obj
}

// 上传附件
const selectFiles = (fun) => {
	const input = document.createElement("input")
	input.setAttribute("type", "file")
	input.setAttribute("name", "fujian")
	input.click()
	input.onchange = function() {
		fun && fun(files)
	}
	input.remove()
}

// 判断清空无效字段数据
const clearInvalidField = (field) => {
	let InvalidStrList = ["null", "undefined", "0001-01-01T00:00:00"]
	if (InvalidStrList.includes(field)) return null
}

// 批量下载
const download = (fileList) => {
	confirm("请确认下载附件？").then(() => {
		fileList.forEach(function(item, index) {
			setTimeout(() => {
				let a = document.createElement('a'); // 创建a标签
				let e = document.createEvent('MouseEvents'); // 创建鼠标事件对象
				e.initEvent('click', false, false); // 初始化事件对象
				a.href = item.src; // 设置下载地址
				a.download = item.fname; // 设置下载文件名
				a.dispatchEvent(e);
			}, 100 * index)
		})
	}).catch(() => {})
}

// 上传附件显示进度条
const showProgress = (num) => {
	let maskEle = document.getElementById("mask")
	maskEle.style.display = "flex"
	maskEle.innerHTML = `<div id="h-Progress">
      <div class="h-Progress-title">上传进度 ${num}%</div>
      <div class="h-Progress-content">
        <div class="h-Progress-content-b">
          <div class="h-Progress-p" style="width:${num}%"></div>
        </div>
      </div>
    </div>`
}

// 隐藏进度条
const hideProgress = () => {
	let maskEle = document.getElementById("mask")
	maskEle.style.display = "none"
}

// 审核 exFieldNames:Object/Array
const audit = (formId, name, Id, fun) => {
	let txt = name ? `请确认审核 [ ${name} ] ？` : '请确认审核 ？'
	confirm(txt).then(() => {
		kdApis.formAudit({
			formId,
			data: {
				Ids: Id
			}
		}).then(res => {
			if (res) {
				msg(`审核成功！`)
				fun()
			}
		})
	}).catch(() => {})
}

const unAudit = (formId, name, Id, fun) => {
	let txt = name ? `请确认反审核 [ ${name} ] ？` : '请确认反审核 ？'
	confirm(txt).then(() => {
		kdApis.formUnAudit({
			formId,
			data: {
				Ids: Id
			}
		}).then(res => {
			if (res) {
				msg(`反审核成功！`)
				fun()
			}
		})
	}).catch(() => {})
}

// 删除
const remove = (formId, name, Id, fun) => {
	let txt = name ? `请确认删除 [ ${name} ] ？` : '请确认删除 ？'
	confirm(txt).then(() => {
		kdApis.formDelete({
			formId,
			data: {
				Ids: Id
			}
		}).then(res => {
			if (res) {
				msg(`删除成功！`)
				fun()
			}
		})
	}).catch(() => {})
}

const getBirthday = (IdNumber) => {
	let birthday = null
	if (IdNumber.length == 18) {
		let ymd = IdNumber.slice(6, 14)
		birthday = `${ymd.slice(0, 4)}-${ymd.slice(4, 6)}-${ymd.slice(6, 8)}`
	}
	return birthday
}

const getAge = (birthday) => {
	let age = null
	age = $time(new Date()).diff($time(birthday), 'year')
	return age
}

const timeFormat = (time, format) => {
	format = format ? format : 'YYYY-MM-DD HH:mm:ss'
	return $time(time).format(format)
}

const getMenuCoordinate = () => {
	let arr = []
	let menuCoordinate = sessionStorage.getItem('menuCoordinate')
	if (menuCoordinate) arr = JSON.parse(menuCoordinate)
	arr[0] = arr[0] ? arr[0] : 0
	arr[1] = arr[1] ? arr[1] : 0
	return arr
}

const clear = () => {
	localStorage.removeItem('userInfo')
	localStorage.removeItem('myInfo')
	localStorage.removeItem('memberInfo')
	// localStorage.clear()
	// sessionStorage.clear()
}

const getName = (list, val, valName, backName) => {
	if (!list || list.length == 0) return
	let arr = list.filter(it => it[valName] == val)
	if (!arr.length) return
	return arr[0][backName]
}

const chooseImg = (count, fun) => {
	uni.chooseFile({
		count,
		type: 'image',
		success: async (data) => {
			let fileList = []
			for (let item of data.tempFiles) {
				if (item.size > 20 * 1024 * 1024) {
					msg(`过滤过大附件 [ ${item.name} ][ ${(item.size / 1024 / 1024).toFixed(2)}M ]`, "error")
					item.tooBig = true
				}
				if (item.name.includes("exe")) {
					msg(`过滤文件 [ ${item.name} ][ ${(item.size / 1024 / 1024).toFixed(2)}M ]`, "error")
					item.tooDanger = true
				}
				if (!item.tooBig && !item.tooDanger) {
					fileList.push(item)
				}
			}
			fun(fileList)
		}
	})
}

const chooseFile = (count, fun) => {
	uni.chooseFile({
		count,
		success: async (data) => {
			let fileList = []
			for (let item of data.tempFiles) {
				if (item.size > 20 * 1024 * 1024) {
					msg(`过滤过大附件 [ ${item.name} ][ ${(item.size / 1024 / 1024).toFixed(2)}M ]`, "error")
					item.tooBig = true
				}
				if (item.name.includes("exe")) {
					msg(`过滤文件 [ ${item.name} ][ ${(item.size / 1024 / 1024).toFixed(2)}M ]`, "error")
					item.tooDanger = true
				}
				if (!item.tooBig && !item.tooDanger) {
					fileList.push(item)
				}
			}
			fun(fileList)
		}
	})
}

const getFStatus = (FStatus) => {
	let obj = {
		"-1": "退回",
		0: "保存",
		1: "提交",
		2: "审批中",
		3: "通过",
		4: "驳回",
		5: "启用",
		7: "关闭",
		9: "完成",
		10: "归档"
	}
	return obj[FStatus] ? obj[FStatus] : FStatus
}

const base64ToUint8Array = (base64) => {
	var binary = atob(base64)
	var len = binary.length
	var uint8Array = new Uint8Array(len)
	for (var i = 0; i < len; i++) {
		uint8Array[i] = binary.charCodeAt(i)
	}
	return uint8Array
}

export {
	msg,
	confirm,
	getType,
	jsonToUrl,
	urlToJson,
	hrefQueryString,
	detectZoom,
	isIE,
	arraytoTree,
	treeToArray,
	checkForm,
	hIncludes,
	contrastArr,
	selectFiles,
	clearInvalidField,
	download,
	showProgress,
	hideProgress,
	audit,
	unAudit,
	remove,
	getBirthday,
	getAge,
	getMenuCoordinate,
	clear,
	getName,
	chooseImg,
	chooseFile,
	timeFormat,
	getFStatus,
	base64ToUint8Array
}